package com.bestv.search.common.service.impl;

import com.bestv.search.common.dao.SysUserDao;
import com.bestv.search.common.dataSource.DataSourceKey;
import com.bestv.search.common.model.SysRole;
import com.bestv.search.common.model.SysUser;
import com.bestv.search.common.model.UserExistsException;
import com.bestv.search.common.model.uid.UID;
import com.bestv.search.common.service.SysUserManager;
import org.acegisecurity.providers.dao.DaoAuthenticationProvider;
import org.acegisecurity.providers.encoding.PasswordEncoder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.List;

public class SysUserManagerImpl implements SysUserManager {
    protected final Log log = LogFactory.getLog(getClass());
    private DaoAuthenticationProvider authenticationProvider;
    private SysUserDao sysUserDao;

    public SysUserDao getSysUserDao() {
        return sysUserDao;
    }

    public void setSysUserDao(SysUserDao sysUserDao) {
        this.sysUserDao = sysUserDao;
    }

    public DaoAuthenticationProvider getAuthenticationProvider() {
        return authenticationProvider;
    }

    public void setAuthenticationProvider(DaoAuthenticationProvider authenticationProvider) {
        this.authenticationProvider = authenticationProvider;
    }

    @Override
    public SysUser getUserById(DataSourceKey key, Long id) {
        return sysUserDao.get(id);
    }

    @Override
    public List<SysUser> getUserByName(DataSourceKey key, String name) {
        log.debug("getUserByName dose not support");
        return null;
    }

    @Override
    public List<SysUser> getUserByRole(DataSourceKey key, SysRole role) {
        log.debug("getUserByRole dose not support");
        return null;
    }

    @Override
    public List<SysUser> getUsers(DataSourceKey key) {
        return sysUserDao.getAll();
    }

    @Override
    public SysUser saveUser(DataSourceKey key, SysUser user) throws UserExistsException {
        if (authenticationProvider != null) {
            PasswordEncoder psdEncoder = authenticationProvider.getPasswordEncoder();
            if (psdEncoder != null) {
                boolean isEncode = false;
                if (user.getId() == 0L) {
                    // if new user, should be encoded for ever
                    log.debug("id: " + user.getId());
                    user.setLoginName(user.getLoginName().toLowerCase());
                    isEncode = true;
                } else {
                    // not new User
                    String oldPsd = sysUserDao.getPasswordByLoginName(user.getLoginName());
                    String newPsd = user.getPassword();
                    if (!newPsd.equals(oldPsd))
                        isEncode = true;
                }
                if (isEncode)
                    user.setPassword(psdEncoder.encodePassword(user.getPassword(), null));
            } else {
                log.warn("PasswordEncoder not set on AuthenticationProvider, skipping password encryption...");
            }
        } else {
            log.warn("AuthenticationProvider not set, skipping password encryption...");
        }
        try {
            if (user.getId() == 0L) {
                user.setId(new Long(UID.getUID(user)));
            }
            sysUserDao.saveOrUpdate(user);
        } catch (Exception e) { // needed for JPA
            log.warn(e.getMessage());
            throw new UserExistsException("User '" + user.getUsername() + "' already exists!");
        }
        return user;
    }

    @Override
    public SysUser getUserByLoginName(DataSourceKey key, String loginName) {
        return sysUserDao.getUserByLoginName(loginName.toLowerCase());
    }
}
